﻿using GMap.NET;
using GMap.NET.WindowsForms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;

namespace GMapMarkerLib
{
    public class GMapArrowLineMarker : GMapMarker
    {
        public PointLatLng startPoint;
        public PointLatLng endPoint;
        /// <summary>
        /// 线段与水平线的夹角（角度值）
        /// </summary>
        public float Angle { get; set; }

        /// <summary>
        /// 线段与水平线的夹角（弧度值）
        /// </summary>
        public float AngleRadian { get; set; }
        /// <summary>
        /// 线宽
        /// </summary>
        public float Width = 1;

        public bool IsShowArrow;

        public GMapArrowLineMarker(PointLatLng start, PointLatLng end, float width = 1, bool isShowArrow = true) : base(start)
        {
            startPoint = start;
            endPoint = end;
            IsShowArrow = isShowArrow;
            Width = width;
        }

        public override void OnRender(Graphics g)
        {
            GPoint ep = this.Overlay.Control.FromLatLngToLocal(endPoint);
            GPoint sp = this.Overlay.Control.FromLatLngToLocal(startPoint);

            Point start = LocalPosition;
            Point end = new Point((int)(LocalPosition.X + ep.X - sp.X), (int)(LocalPosition.Y + ep.Y - sp.Y));

            ToolTip.Offset = new Point((int)Width, (int)(ep.Y - sp.Y) / 2);

            AngleRadian = (float)Math.Atan2(ep.Y - sp.Y, ep.X - sp.X);//弧度值
            Angle = (float)Math.Round(180 / Math.PI * AngleRadian, 2);//角度值

            Matrix matrix = new Matrix();
            matrix.Rotate(-(float)Angle);
            GraphicsPath line1 = new GraphicsPath();
            line1.AddLine(start, end);
            line1.Transform(matrix);

            var P0 = line1.PathPoints[0];
            var P1 = line1.PathPoints[1];


            //计算直线框
            GraphicsPath pathLine = new GraphicsPath();
            PointF[] pointfs = new PointF[]
            {
                new PointF(P0.X, P0.Y - Width / 2),
                new PointF(P1.X, P1.Y - Width / 2),
                new PointF(P1.X, P1.Y + Width / 2),
                new PointF(P0.X, P0.Y + Width / 2),
            };
            pathLine.AddLines(pointfs);
            matrix = new Matrix();
            matrix.Rotate((float)Angle);
            pathLine.Transform(matrix);
            g.FillPath(Brushes.Blue, pathLine);

            //计算并绘制箭头框
            if (IsShowArrow)
            {
                float minlength = 5 * Width;
                float dx = P0.X - minlength / 2;
                GraphicsPath arrowPath = new GraphicsPath();
                for (int j = 1; j < Math.Ceiling(Math.Abs(P1.X - P0.X + minlength / 2) / minlength); j++)
                {
                    PointF[] points = new PointF[]
                    {
                        new PointF(dx + minlength * j, P1.Y - Width / 2),
                        new PointF(dx + minlength * j + Width / 2f, P1.Y - Width / 2),
                        new PointF(dx + minlength * j + Width, P1.Y),
                        new PointF(dx + minlength * j + Width / 2f, P1.Y + Width / 2),
                        new PointF(dx + minlength * j, P1.Y + Width / 2),
                        new PointF(dx + minlength * j + Width / 2f, P1.Y)
                    };
                    arrowPath.StartFigure();
                    arrowPath.AddLines(points);
                }
                arrowPath.Transform(matrix);
                g.FillPath(Brushes.White, arrowPath);
            }
        }

        public override void Dispose()
        {
            base.Dispose();
        }
    }
}
